package com.i_art_engineer.meigong.photo.filter;

import android.content.Context;
import android.graphics.Bitmap;

import com.i_art_engineer.meigong.R;
import com.i_art_engineer.meigong.photo.filter.base.Image3x3TextureSamplingFilter;
import com.i_art_engineer.meigong.photo.filter.base.ImageBrightnessFilter;
import com.i_art_engineer.meigong.photo.filter.base.ImageColorInvertFilter;
import com.i_art_engineer.meigong.photo.filter.base.ImageGrayscaleFilter;
import com.i_art_engineer.meigong.photo.filter.base.ImageHueFilter;
import com.i_art_engineer.meigong.photo.filter.base.ImagePixelationFilter;
import com.i_art_engineer.meigong.photo.filter.base.ImageSepiaFilter;
import com.i_art_engineer.meigong.photo.filter.base.ImageSharpenFilter;
import com.i_art_engineer.meigong.photo.filter.base.ImageSobelEdgeDetection;
import com.i_art_engineer.meigong.photo.filter.base.ImageContrastFilter;
import com.i_art_engineer.meigong.photo.filter.base.ImageGammaFilter;
import com.i_art_engineer.meigong.photo.filter.effect.A1977Filter;
import com.i_art_engineer.meigong.photo.filter.effect.AmaroFilter;
import com.i_art_engineer.meigong.photo.filter.effect.BrannanFilter;
import com.i_art_engineer.meigong.photo.filter.effect.EarlybirdFilter;
import com.i_art_engineer.meigong.photo.filter.effect.HefeFilter;
import com.i_art_engineer.meigong.photo.filter.effect.HudsonFilter;
import com.i_art_engineer.meigong.photo.filter.effect.InkwellFilter;
import com.i_art_engineer.meigong.photo.filter.effect.LomofiFilter;
import com.i_art_engineer.meigong.photo.filter.effect.NashvilleFilter;
import com.i_art_engineer.meigong.photo.filter.effect.NormalFilter;
import com.i_art_engineer.meigong.photo.filter.effect.OriginFilter;
import com.i_art_engineer.meigong.photo.filter.effect.RiseFilter;
import com.i_art_engineer.meigong.photo.filter.effect.SierraFilter;
import com.i_art_engineer.meigong.photo.filter.effect.SutroFilter;
import com.i_art_engineer.meigong.photo.filter.effect.ToasterFilter;
import com.i_art_engineer.meigong.photo.filter.effect.TwoFilter;
import com.i_art_engineer.meigong.photo.filter.effect.ValenciaFilter;
import com.i_art_engineer.meigong.photo.filter.effect.WaldenFilter;
import com.i_art_engineer.meigong.photo.filter.effect.XproIIFilter;

import java.util.LinkedList;
import java.util.List;

/**
 *
 */
public class FilterTools {

    private static FilterList filters;

    public static Bitmap getBmp() {
        return mbmp;
    }

    public static void setBmp(Bitmap bmp) {
        mbmp = bmp;
    }

    private static Bitmap mbmp;
    /**
     * 支持的滤镜
     */
    public enum FilterType {
//        CONTRAST,
//        INVERT,
//        PIXELATION,
//        HUE,
//        GAMMA,
//        BRIGHTNESS,
//        SEPIA,
//        GRAYSCALE,
//        SHARPEN,
//        SOBEL_EDGE_DETECTION,
        ORIGIN,
        LOMOFI,
        BRANNAN,
        RISE,
        NORMAL,
        VALENCIA,
        LORDKELVIN,
        HEFE,
        A1977,
        HUDSON,
        INKEWLL,
        NASHVILLE,
        AMARO,
        SIERRA,
        SUTRO,
        TOASTER,
        EARLYBIRD,
        WALDEN,
        XPROLL,
        TWO,


    }

    public static FilterList getFilterList() {
        if (filters == null) {
            filters = new FilterList();
            filters.addFilter("原图", R.drawable.if_lomofi, FilterType.ORIGIN);//lomo经典
            filters.addFilter("LOMO", R.drawable.if_lomofi, FilterType.LOMOFI);//lomo经典
            filters.addFilter("淡雅", R.drawable.if_brannan, FilterType.BRANNAN);//淡雅
            filters.addFilter("云端", R.drawable.if_rise, FilterType.RISE);//云端
//            filters.addFilter("Normal", R.drawable.if_normal, FilterType.NORMAL);//自然
            filters.addFilter("自然", R.drawable.if_normal, FilterType.NORMAL);//自然
            filters.addFilter("白露", R.drawable.if_valencia, FilterType.VALENCIA);//白露
            filters.addFilter("魅惑", R.drawable.if_lordkelvin, FilterType.LORDKELVIN);
            filters.addFilter("蜜柚", R.drawable.if_hefe, FilterType.HEFE);
            filters.addFilter("甜美可人", R.drawable.if_1977, FilterType.A1977);
            filters.addFilter("蓝调", R.drawable.if_hudson, FilterType.HUDSON);
            filters.addFilter("黑白", R.drawable.if_inkwell, FilterType.INKEWLL);
            filters.addFilter("经典", R.drawable.if_nashville, FilterType.NASHVILLE);
            filters.addFilter("日系", R.drawable.if_amaro, FilterType.AMARO);
            filters.addFilter("柳丁", R.drawable.if_sierra, FilterType.SIERRA);
            filters.addFilter("典雅", R.drawable.if_sutro, FilterType.SUTRO);
            filters.addFilter("迷幻", R.drawable.if_toaster, FilterType.TOASTER);
            filters.addFilter("典雅", R.drawable.if_earlybird, FilterType.EARLYBIRD);
            filters.addFilter("清凉", R.drawable.if_walden, FilterType.WALDEN);
            filters.addFilter("靓丽", R.drawable.if_xproii, FilterType.XPROLL);


//            filters.addFilter("Contrast", R.drawable.if_1977, FilterType.CONTRAST);
//            filters.addFilter("Invert", R.drawable.if_1977, FilterType.INVERT);
//            filters.addFilter("Pixelation", R.drawable.if_1977, FilterType.PIXELATION);
//            filters.addFilter("Hue", R.drawable.if_1977, FilterType.HUE);
//            filters.addFilter("Gamma", R.drawable.if_1977, FilterType.GAMMA);
//            filters.addFilter("Brightness", R.drawable.if_1977, FilterType.BRIGHTNESS);
//            filters.addFilter("Sepia", R.drawable.if_1977, FilterType.SEPIA);
//            filters.addFilter("Grayscale", R.drawable.if_1977, FilterType.GRAYSCALE);
//            filters.addFilter("Sharpness", R.drawable.if_1977, FilterType.SHARPEN);
//            filters.addFilter("Sobel Edge Detection", R.drawable.if_1977, FilterType.SOBEL_EDGE_DETECTION);
        }
        return filters;
    }

    /**
     * 创建对应的滤镜
     *
     * @param context
     * @param type
     * @return
     */
    public static GPUImageFilter createFilterForType(final Context context, final FilterType type) {
        switch (type) {
//            case CONTRAST:
//                return new ImageContrastFilter(2.0f);
//            case GAMMA:
//                return new ImageGammaFilter(2.0f);
//            case INVERT:
//                return new ImageColorInvertFilter();
//            case PIXELATION:
//                return new ImagePixelationFilter();
//            case HUE:
//                return new ImageHueFilter(90.0f);
//            case BRIGHTNESS:
//                return new ImageBrightnessFilter(1.5f);
//            case GRAYSCALE:
//                return new ImageGrayscaleFilter();
//            case SEPIA:
//                return new ImageSepiaFilter();
//            case SHARPEN:
//                ImageSharpenFilter sharpness = new ImageSharpenFilter();
//                sharpness.setSharpness(2.0f);
//                return sharpness;
//            case SOBEL_EDGE_DETECTION:
//                return new ImageSobelEdgeDetection();
            case ORIGIN:
                return new OriginFilter(context);
            case LOMOFI:
                return new LomofiFilter(context);
            case AMARO:
                return new AmaroFilter(context);
            case BRANNAN:
                return new BrannanFilter(context);
            case EARLYBIRD:
                return new EarlybirdFilter(context);
            case HEFE:
                return new HefeFilter(context);
            case LORDKELVIN:
                return new LomofiFilter(context);
            case HUDSON:
                return new HudsonFilter(context);
            case INKEWLL:
                return new InkwellFilter(context);
            case NASHVILLE:
                return new NashvilleFilter(context);
            case NORMAL:
                return new NormalFilter(context);
            case RISE:
                return new RiseFilter(context);
            case SIERRA:
                return new SierraFilter(context);
            case SUTRO:
                return new SutroFilter(context);
            case TOASTER:
                return new ToasterFilter(context);
            case VALENCIA:
                return new ValenciaFilter(context);
            case WALDEN:
                return new WaldenFilter(context);
            case XPROLL:
                return new XproIIFilter(context);
            case A1977:
                return new A1977Filter(context);
            case TWO:
                return new TwoFilter(context,getBmp());//设置处理后的图片

            default:
                throw new IllegalStateException("No filter of that type!");
        }
    }

    public static class FilterList {

        public List<String> names = new LinkedList<>();
        public List<Integer> resources = new LinkedList<>();
        public List<FilterType> filters = new LinkedList<>();

        public void addFilter(final String name, int resId, final FilterType filter) {
            names.add(name);
            resources.add(resId);
            filters.add(filter);
        }

        public int count()
        {
            return names.size();
        }

    }

    public static class FilterAdjuster {

        private final Adjuster<? extends GPUImageFilter> adjuster;

        public FilterAdjuster(final GPUImageFilter filter) {
            if (filter instanceof ImageSharpenFilter) {
                adjuster = new SharpnessAdjuster().filter(filter);
            } else if (filter instanceof ImageSepiaFilter) {
                adjuster = new SepiaAdjuster().filter(filter);
            } else if (filter instanceof ImageContrastFilter) {
                adjuster = new ContrastAdjuster().filter(filter);
            } else if (filter instanceof ImageGammaFilter) {
                adjuster = new GammaAdjuster().filter(filter);
            } else if (filter instanceof ImageBrightnessFilter) {
                adjuster = new BrightnessAdjuster().filter(filter);
            } else if (filter instanceof ImageSobelEdgeDetection) {
                adjuster = new SobelAdjuster().filter(filter);
            } else if (filter instanceof Image3x3TextureSamplingFilter) {
                adjuster = new GPU3x3TextureAdjuster().filter(filter);
            } else if (filter instanceof ImageHueFilter) {
                adjuster = new HueAdjuster().filter(filter);
            } else if (filter instanceof ImagePixelationFilter) {
                adjuster = new PixelationAdjuster().filter(filter);
            } else {
                adjuster = null;
            }
        }

        public boolean canAdjust() {
            return adjuster != null;
        }

        public void adjust(final int percentage) {
            if (adjuster != null) {
                adjuster.adjust(percentage);
            }
        }

        private abstract class Adjuster<T extends GPUImageFilter> {

            private T filter;

            @SuppressWarnings("unchecked")
            public Adjuster<T> filter(final GPUImageFilter filter) {
                this.filter = (T) filter;
                return this;
            }

            public T getFilter() {
                return filter;
            }

            public abstract void adjust(int percentage);

            protected float range(final int percentage, final float start, final float end) {
                return (end - start) * percentage / 100.0f + start;
            }

            protected int range(final int percentage, final int start, final int end) {
                return (end - start) * percentage / 100 + start;
            }

        }

        private class SharpnessAdjuster extends Adjuster<ImageSharpenFilter> {
            @Override
            public void adjust(final int percentage) {
                getFilter().setSharpness(range(percentage, -4.0f, 4.0f));
            }
        }

        private class PixelationAdjuster extends Adjuster<ImagePixelationFilter> {

            @Override
            public void adjust(final int percentage) {
                getFilter().setPixel(range(percentage, 1.0f, 100.0f));
            }

        }

        private class HueAdjuster extends Adjuster<ImageHueFilter> {

            @Override
            public void adjust(final int percentage) {
                getFilter().setHue(range(percentage, 0.0f, 360.0f));
            }

        }

        private class ContrastAdjuster extends Adjuster<ImageContrastFilter> {

            @Override
            public void adjust(final int percentage) {
                getFilter().setContrast(range(percentage, 0.0f, 2.0f));
            }

        }

        private class GammaAdjuster extends Adjuster<ImageGammaFilter> {

            @Override
            public void adjust(final int percentage) {
                getFilter().setGamma(range(percentage, 0.0f, 3.0f));
            }

        }

        private class BrightnessAdjuster extends Adjuster<ImageBrightnessFilter> {

            @Override
            public void adjust(final int percentage) {
                getFilter().setBrightness(range(percentage, -1.0f, 1.0f));
            }

        }

        private class SepiaAdjuster extends Adjuster<ImageSepiaFilter> {

            @Override
            public void adjust(final int percentage) {
                getFilter().setIntensity(range(percentage, 0.0f, 2.0f));
            }

        }

        private class SobelAdjuster extends Adjuster<ImageSobelEdgeDetection> {

            @Override
            public void adjust(final int percentage) {
                getFilter().setLineSize(range(percentage, 0.0f, 5.0f));
            }

        }

        private class GPU3x3TextureAdjuster extends Adjuster<Image3x3TextureSamplingFilter> {

            @Override
            public void adjust(final int percentage) {
                getFilter().setLineSize(range(percentage, 0.0f, 5.0f));
            }

        }

    }

}
